/*
 * Copyright (c) 2002-2004, xRhino, Inc.
 *
 * This library is free software; you can redistribute and/or modify
 * it under the terms of the dual license distributed with this source
 * package (a combined Trolltech QPL/GPL-compatible license)
 *
 * Under this dual license scheme, a separate license is available for use of 
 * this code with a proprietary (closed) system. For more information on the 
 * license, please see the LICENSE file distributed with this source package.
 */
#ifndef SUGPATHELEMENT_H
#define SUGPATHELEMENT_H

#include "SugTypes.h"
#include "SugElement.h"
#include "SugPathSeg.h"
#include "SugPathSegArc.h"
#include "SugPathSegCurvetoCubic.h"
#include "SugPathSegCurvetoCubicSmooth.h"
#include "SugPathSegCurvetoQuadratic.h"
#include "SugPoint.h"

/**
 * The control class for SVGPath elements.  This class governs and SVG Path 
 * its entirety and is used as one of the classes in the parsed vector.
 */
class SugPathElement: public SugElement
{
  protected:
   /**
    * The path length
    */
    unsigned long mPathLength;

   /**
    * The actual path segments
    */
   vector<SugPathSeg*> mPathSegList;

   /**
    * Helper function for the path parsing. Tokenizes the path no
    * matter what format the string might be in.
    *
    * @param str The string to be tokenized. It is modified in the
    *            function.
    * @param tok The token as a result of the call to this function.
    * @return The same pointer as tok.
    */
   char* getPathCommandToken(char** str, char* tok);

   
  public:
   /**
    * Returns the path length
    */
    unsigned long getPathLength();

   /**
    * This is from the IDL, not sure if it has a use.
    */
   double getTotalLength();

   /**
    * This is from the IDL, not sure if it has a use.
    */
   SugPoint* getPointAtLength(SugRealType distance);

   /**
    * This is from the IDL, not sure if it has a use.
    */
   unsigned long getPathSegAtLength(SugRealType distance);

   /**
    * Returns the path segment list
    */
   vector<SugPathSeg*>* getPathSegList();

   /**
    * Sets the path segment list
    */
   vector<SugPathSeg*>* setPathSegList(vector<SugPathSeg*>* newPathSegList);

   /**
    * Factory for ClosePath
    */
   SugPathSeg* createSugPathSetClosePath();

   /**
    * Factory for MovetoAbs
    */
   SugPathSeg* createSugPathSegMovetoAbs(SugRealType newX, SugRealType newY);

   /**
    * Factory for MovetoRel
    */
   SugPathSeg* createSugPathSegMovetoRel(SugRealType newX, SugRealType newY);

   /**
    * Factory for LinetoAbs
    */
   SugPathSeg* createSugPathSegLinetoAbs(SugRealType newX, SugRealType newY);

   /**
    * Factory for LinetoRel
    */
   SugPathSeg* createSugPathSegLinetoRel(SugRealType newX, SugRealType newY);

   /**
    * Factory for CurvetoCubicAbs
    */
   SugPathSegCurvetoCubic* createSugPathSegCurvetoCubicAbs(SugRealType newX, SugRealType newY, SugRealType newX1, SugRealType newY1, SugRealType newX2, SugRealType newY2);

   /**
    * Factory for CurvetoCubicRel
    */
   SugPathSegCurvetoCubic* createSugPathSegCurvetoCubicRel(SugRealType newX, SugRealType newY, SugRealType newX1, SugRealType newY1, SugRealType newX2, SugRealType newY2);

   /**
    * Factory for CurvetoQuadraticAbs
    */
   SugPathSegCurvetoQuadratic* createSugPathSegCurvetoQuadraticAbs(SugRealType newX, SugRealType newY, SugRealType newX1, SugRealType newY1);

   /**
    * Factory for CurvetoQuadraticRel
    */
   SugPathSegCurvetoQuadratic* createSugPathSegCurvetoQuadraticRel(SugRealType newX, SugRealType newY, SugRealType newX1, SugRealType newY1);

   /**
    * Factory for ArcAbs
    */
   SugPathSegArc* createSugPathSegArcAbs(SugRealType newX, SugRealType newY, SugRealType newR1, SugRealType newR2, SugRealType newAngle, bool newLargeArcFlag, bool newSweepFlag);

   /**
    * Factory for ArcRel
    */
   SugPathSegArc* createSugPathSegArcRel(double newX, SugRealType newY, SugRealType newR1, SugRealType newR2, SugRealType newAngle, bool newLargeArcFlag, bool newSweepFlag);

   /**
    * Factory for LinetoHorizontalAbs
    */
   SugPathSeg* createSugPathSegLinetoHorizontalAbs(SugRealType newX);

   /**
    * Factory for LinetoHorizontalRel
    */
   SugPathSeg* createSugPathSegLinetoHorizontalRel(SugRealType newX);

   /**
    * Factory for LinetoVerticalAbs
    */
   SugPathSeg* createSugPathSegLinetoVerticalAbs(SugRealType newY);

   /**
    * Factory for LinetoVerticalRel
    */
   SugPathSeg* createSugPathSegLinetoVerticalRel(SugRealType newY);

   /**
    * Factory for CurvetoCubicSmoothAbs
    */
   SugPathSegCurvetoCubicSmooth* createSugPathSegCurvetoCubicSmoothAbs(SugRealType newX, SugRealType newY, SugRealType newX2, SugRealType newY2);

   /**
    * Factory for CurvetoCubicSmoothRel
    */
   SugPathSegCurvetoCubicSmooth* createSugPathSegCurvetoCubicSmoothRel(SugRealType newX, SugRealType newY, SugRealType newX2, SugRealType newY2);

   /**
    * Factory for CurvetoQuadraticSmoothAbs
    */
   SugPathSeg* createSugPathSegCurvetoQuadraticSmoothAbs(SugRealType newX, SugRealType newY);

   /**
    * Factory for CurvetoQuadraticSmoothRel
    */
   SugPathSeg* createSugPathSegCurvetoQuadraticSmoothRel(SugRealType newX, SugRealType newY);

   /**
    * Gets the specified attribute's value in path command list format.
    *
    * @param The name of the attribute we are getting the value for.
    * @param The value of the attribute.
    * @return Boolean value indicating whether or not the attribute
    *         exists in this element.
    */
   bool getPathCommandsAttribute(char* attrName,
                                 vector<SugPathSeg*>& attrValue);

   /**
    * The class constructor
    */
   SugPathElement();

   /**
    * The class destructor
    */
   ~SugPathElement();

};

#endif
